
package com.smartboot.plus.launch;

import com.smartboot.plus.plugins.PluginConfig;
import com.smartboot.plus.utils.Func;
import com.smartboot.plus.utils.INetUtil;
import org.apache.commons.lang3.StringUtils;
import tech.smartboot.feat.cloud.annotation.Bean;
import tech.smartboot.mqtt.common.util.MqttUtil;

import java.util.Properties;


/**
 * 启动参数拓展
 * 先尝试从 JVM 启动参数中获取系统属性 -Dxx=yy
 * 如果没找到，则尝试从 操作系统环境变量 中获取
 */
@Bean(order = Integer.MIN_VALUE)
public class LauncherService {
    public static final String CONFIG_OPENAPI_HOST = "openApi.host";
    public static final String CONFIG_CLUSTER_DISCOVERY_SPI_LOCAL_PORT = "cluster.tcpDiscoverySpiLocalPort";

    public static final String CONFIG_CLUSTER_COMMUNICATION_SPI_LOCAL_PORT = "cluster.tcpCommunicationSpiLocalPort";

    public static final String CONFIG_CLUSTER_ADDRESSES = "cluster.addresses";


    public static final String CONFIG_CLUSTER_WORK_DIRECTORY = "cluster.workDirectory";
    public static final String CONFIG_NODE_TYPE = "node.type";


    public static final String CONFIG_AUTH_USER_NAME = "auth.username";

    public static final String CONFIG_AUTH_PASSWORD = "auth.password";


    public static final String CONFIG_USER_USER_NAME = "user.username";

    public static final String CONFIG_USER_PASSWORD = "user.password";

    @Bean
    public Properties launcher(PluginConfig pluginConfig) {
        Properties props = System.getProperties();
        initOpenApiConfig(pluginConfig);
        initClusterConfig(pluginConfig);
        initAuthConfig(pluginConfig);
        initUserConfig(pluginConfig);
        initNodeConfig(pluginConfig);

        PropsUtil.setProperty(props, CONFIG_OPENAPI_HOST, StringUtils.defaultString(System.getProperty(CONFIG_OPENAPI_HOST, System.getenv(CONFIG_OPENAPI_HOST)), INetUtil.getHostIp()));

        PropsUtil.setProperty(props, CONFIG_CLUSTER_DISCOVERY_SPI_LOCAL_PORT, StringUtils.defaultString(System.getProperty(CONFIG_CLUSTER_DISCOVERY_SPI_LOCAL_PORT, System.getenv(CONFIG_CLUSTER_DISCOVERY_SPI_LOCAL_PORT)), "47500"));
        PropsUtil.setProperty(props, CONFIG_CLUSTER_COMMUNICATION_SPI_LOCAL_PORT, StringUtils.defaultString(System.getProperty(CONFIG_CLUSTER_COMMUNICATION_SPI_LOCAL_PORT, System.getenv(CONFIG_CLUSTER_COMMUNICATION_SPI_LOCAL_PORT)), "47600"));
        PropsUtil.setProperty(props, CONFIG_CLUSTER_ADDRESSES, StringUtils.defaultString(System.getProperty(CONFIG_CLUSTER_ADDRESSES, System.getenv(CONFIG_CLUSTER_ADDRESSES)), INetUtil.getHostIp()));


        PropsUtil.setProperty(props, CONFIG_CLUSTER_WORK_DIRECTORY, StringUtils.defaultString(System.getProperty(CONFIG_CLUSTER_WORK_DIRECTORY, System.getenv(CONFIG_CLUSTER_WORK_DIRECTORY)), ""));

        PropsUtil.setProperty(props, CONFIG_AUTH_USER_NAME, StringUtils.defaultString(System.getProperty(CONFIG_AUTH_USER_NAME, System.getenv(CONFIG_AUTH_USER_NAME)), ""));
        PropsUtil.setProperty(props, CONFIG_AUTH_PASSWORD, StringUtils.defaultString(System.getProperty(CONFIG_AUTH_PASSWORD, System.getenv(CONFIG_AUTH_PASSWORD)), ""));

        PropsUtil.setProperty(props, CONFIG_USER_USER_NAME, StringUtils.defaultString(System.getProperty(CONFIG_USER_USER_NAME, System.getenv(CONFIG_USER_USER_NAME)), ""));
        PropsUtil.setProperty(props, CONFIG_USER_PASSWORD, StringUtils.defaultString(System.getProperty(CONFIG_USER_PASSWORD, System.getenv(CONFIG_USER_PASSWORD)), ""));

        PropsUtil.setProperty(props, CONFIG_NODE_TYPE, StringUtils.defaultString(System.getProperty(CONFIG_NODE_TYPE, System.getenv(CONFIG_NODE_TYPE)), "replicant"));

        return props;
    }

    public void initOpenApiConfig(PluginConfig pluginConfig) {

        PluginConfig.HttpConfig featApiConfig = pluginConfig.getHttpConfig();
        if (featApiConfig == null) {
            featApiConfig = new PluginConfig.HttpConfig();
        }
        MqttUtil.updateConfig(featApiConfig, "openApi");
        if (Func.isNotEmpty(featApiConfig.getHost())) {
            System.setProperty(CONFIG_OPENAPI_HOST, featApiConfig.getHost());
        }
    }

    public void initClusterConfig(PluginConfig pluginConfig) {


        PluginConfig.ClusterConfig clusterConfig = pluginConfig.getClusterConfig();
        if (clusterConfig == null) {
            clusterConfig = new PluginConfig.ClusterConfig();
        }
        MqttUtil.updateConfig(clusterConfig, "cluster");


        if (Func.isNotEmpty(clusterConfig.getTcpDiscoverySpiLocalPort())) {
            System.setProperty(CONFIG_CLUSTER_DISCOVERY_SPI_LOCAL_PORT, clusterConfig.getTcpDiscoverySpiLocalPort());
        }
        if (Func.isNotEmpty(clusterConfig.getTcpCommunicationSpiLocalPort())) {
            System.setProperty(CONFIG_CLUSTER_COMMUNICATION_SPI_LOCAL_PORT, clusterConfig.getTcpCommunicationSpiLocalPort());
        }
        if (Func.isNotEmpty(clusterConfig.getAddresses()) && clusterConfig.getAddresses().size() > 0) {
            String addressStr = String.join(",", clusterConfig.getAddresses());
            System.setProperty(CONFIG_CLUSTER_ADDRESSES, addressStr);
        }
        if (Func.isNotEmpty(clusterConfig.getWorkDirectory())) {
            System.setProperty(CONFIG_CLUSTER_WORK_DIRECTORY, clusterConfig.getWorkDirectory());
        }
    }


    private void initUserConfig(PluginConfig pluginConfig) {

        PluginConfig.UserConfig userConfig = pluginConfig.getUserConfig();

        MqttUtil.updateConfig(userConfig, "user");

        if (Func.isNotEmpty(userConfig.getUsername())) {
            System.setProperty(CONFIG_USER_USER_NAME, userConfig.getUsername());
        }
        if (Func.isNotEmpty(userConfig.getPassword())) {
            System.setProperty(CONFIG_USER_PASSWORD, userConfig.getPassword());
        }
    }

    private void initAuthConfig(PluginConfig pluginConfig) {

        PluginConfig.AuthConfig config = pluginConfig.getAuthConfig();
        MqttUtil.updateConfig(config, "auth");
//      LOGGER.debug("auth config:{}", JSON.toJSONString(config));

        if (StringUtils.isNotBlank(config.getUsername())) {
            System.setProperty(CONFIG_AUTH_USER_NAME, config.getUsername());
        }
        if (StringUtils.isNotBlank(config.getPassword())) {
            System.setProperty(CONFIG_AUTH_PASSWORD, config.getPassword());
        }
    }

    private void initNodeConfig(PluginConfig pluginConfig) {

        PluginConfig.NodeConfig config = pluginConfig.getNodeConfig();
        MqttUtil.updateConfig(config, "node");
//      LOGGER.debug("auth config:{}", JSON.toJSONString(config));

        if (StringUtils.isNotBlank(config.getType())) {
            System.setProperty(CONFIG_NODE_TYPE, config.getType());
        }


    }
}